package me.sealer.plugins;

import me.sealer.plugins.util.FileCountUtil;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Mojo(name = "count-lines")
public class CountLinesMojo extends AbstractMojo {
    private static final String[] INCLUDES_DEFAULT = {"java", "xml", "properties"};

    @Parameter(defaultValue = "${project.basedir}")
    private File baseDir;

    @Parameter(defaultValue = "${project.build.sourceDirectory}")
    private File sourceDirectory;

    @Parameter(defaultValue = "${project.build.testSourceDirectory}")
    private File testSourceDirectory;

    @Parameter(defaultValue = "${project.build.resources}")
    private List<Resource> resources;

    @Parameter(defaultValue = "${project.build.testResources}")
    private List<Resource> testResources;

    @Parameter
    private String[] includes;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        if (includes == null || includes.length == 0) {
            includes = INCLUDES_DEFAULT;
        }

        try {
            countDir(sourceDirectory);
            countDir(testSourceDirectory);
            for (Resource resource : resources) {
                countDir(new File(resource.getDirectory()));
            }

            for (Resource resource : testResources) {
                countDir(new File(resource.getDirectory()));
            }
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to count lines of code", e);
        }
    }

    /**
     * 统计dir目录下的所有文件的行数
     *
     * @param dir
     * @throws IOException
     */
    private void countDir(File dir) throws IOException {
        if (!dir.exists()) {
            return;
        }

        List<File> collected = new ArrayList<>();
        FileCountUtil.collectFiles(collected, dir, this.includes);

        int lines = 0;
        for (File file : collected) {
            lines += countLine(file);
        }

        String path = dir.getAbsolutePath().substring(baseDir.getAbsolutePath().length());
        getLog().info(path + ": " + lines + " lines of code in " + collected.size() + " files");
    }

    /**
     * 统计file文件的行数
     *
     * @param file
     * @return
     */
    private int countLine(File file) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(file));
        int line = 0;
        while (br.ready()) {
            br.readLine();
            line++;
        }

        br.close();
        return line;
    }

    public void setBaseDir(File baseDir) {
        this.baseDir = baseDir;
    }

    public void setSourceDirectory(File sourceDirectory) {
        this.sourceDirectory = sourceDirectory;
    }

    public void setTestSourceDirectory(File testSourceDirectory) {
        this.testSourceDirectory = testSourceDirectory;
    }

    public void setResources(List<Resource> resources) {
        this.resources = resources;
    }

    public void setTestResources(List<Resource> testResources) {
        this.testResources = testResources;
    }

    public void setIncludes(String[] includes) {
        this.includes = includes;
    }

}
//maven plugin 学习网址

//http://blog.csdn.net/chinrui/article/details/66472815
//http://blog.csdn.net/chinrui/article/details/66472815
//http://maven.apache.org/guides/plugin/guide-java-plugin-development.html